package dryven.request.controller.result;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import dryven.annotations.DII;
import dryven.config.ApplicationConfiguration;
import dryven.model.di.DependencyService;
import dryven.request.controller.ControllerDescription;
import dryven.request.http.Request;
import dryven.request.http.Response;
import dryven.view.ViewDataDictionary;
import dryven.view.ViewEngine;

public class ViewResult implements ActionResult, OriginatingControllerListener {

	private String _viewClassFile;
	private ViewDataDictionary _viewData;
	private ViewEngine _viewEngine;
	private ControllerDescription _originatingController;
	private DependencyService _di;
	public ViewResult() {
		this(null);
	}
	
	public ViewResult(ViewDataDictionary viewData) {
		super();
		_viewData = viewData;
	}

	public ViewResult(String viewClassFile, ViewDataDictionary viewData) {
		super();
		_viewClassFile = viewClassFile;
		_viewData = viewData;
	}

	@Override
	public ActionResult process(Request req, Response resp) {
		//inject deps
		for (String name : _viewData.getRootValues()) {
			Object o = _viewData.getRootValue(name);
			_di.injectDependencies(req, o);
		}
		
		
		try {
			OutputStream out = resp.getResponseStream();
			Writer w = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
			_viewEngine.renderView("", w, _viewData);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return null;
	}

	public void injectDependencies(
			DependencyService di,
			ViewEngine viewEngine) {
		_viewEngine = viewEngine;
		_di = di;
	}

	@Override
	public void passOriginatingController(ControllerDescription cd) {
		_originatingController = cd;
		if (_viewData == null) {
			return;
		}
		for (String name : _viewData.getRootValues()) {
			Object o = _viewData.getRootValue(name);
			if (o != null
					&& OriginatingControllerListener.class.isAssignableFrom(o
							.getClass())) {
				((OriginatingControllerListener) o)
						.passOriginatingController(cd);
			}
		}
	}
}
